import time
import sys
from threading import Thread

N=5
class Semaphore():


	def __init__(self,startingCount):
		count = startingCount

	def down():
		while count <= 0:
			# We must wait
			self.waitUntilRunning.wait()
			count=count-1


	def up():
		count=count+1
		# notify a waiting thread to wakeup
		if count == 1 :
			self.waitUntilRunning.notify()





class Philosopher (Thread):
	THINKING = 0       
	HUNGRY = 1         
	EATING = 2         
	mutex = Semaphore(1)
	s=Semaphore([N])
		

	def __init__(self,i):
		Thread.__init__(self)
		self.myNumber = i
		myLeft = (i+N-1) % N               #Compute the left neighbor
		myRight = (i+1) % N                 #Compute the right neighbor	
		
	def run(self):
		while True:
			self.think()
			take_forks()                   	# Acquire two forks or block
			eat(self)                         	 #Yum-yum, spahgetti
			put_forks()                  	#Put both forks back on the table
			
	def 	take_forks(self):
		mutex.down()                       # Enter critical region
		state[myNumber] = HUNGRY           # Record the fact that I am hungry
		test(myNumber)                     # Try to acquire two forks
		mutex.up()                         # Leave critical region
		s[myNumber].down()                 # Block if forks were not acquired
		
	def put_forks(self):
		mutex.down()                       # Enter critical region
		state[myNumber] = THINKING         # Philosopher has finished eating
		test(myLeft)                       # See if left neighbor can now eat
		test(myRight)                      # See if right neighbor can now eat
		mutex.up()                         # Leave critical region


	def test(self,k):                # Test philosopher k,
		onLeft = (k+N-1) % N           # K's left neighbor
		onRight = (k+1) % N            # K's right neighbor
		if state[k] == HUNGRY	& state[onLeft] != EATING	& state[onRight] != EATING :
			#Grab those forks
			state[k] = EATING
			s[k].up()


	def think(self):
		print"Philosopher %d is thinking" % self.myNumber
		time.sleep(1000)


	def eat(self):
		print "Philosopher %d is eating" % self.myNumber
		time.sleep(5000)

if __name__=="__main__":
	for i in range(0,N):
		# Create each philosopher and their semaphore
		
		s[i] = Semaphore(0)

		#Start the threads running

		#Philosopher(i).start()
